package com.zsc.boot.once;

import com.zsc.boot.bean.User;
import com.zsc.boot.mapper.UserMapper;
import com.zsc.boot.service.UserService;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

//@Component
public class InsertUser {
    @Resource
    private UserService userService;

    @Resource
    private UserMapper userMapper;

    @Deprecated
    @Scheduled(initialDelay = 5000, fixedRate = Long.MAX_VALUE)
    public void InsertUser() {
        final int INSERT_NUM = 1000;
        for (int i = 0; i < INSERT_NUM; i++) {
            User user = new User();
            user.setUsername("假Hines");
            user.setUserAccount("fakeHines");
            user.setAvatar("https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png");
            user.setGender((byte) 0);
            user.setUserPassword("12345678");
            user.setPhone("1512616163");
            user.setEmail("12345@qq.com");
            user.setUserStatus(0);
            user.setRole(0);
            user.setTags("[]");
            userMapper.insert(user);
        }
    }

    /**
     * 批量插入用户
     */
    //设置定时任务， initialDelay=5000表示项目启动后5秒执行，fixedRate=Long的最大值是让任务只执行一次
//    @Scheduled(initialDelay = 5000,fixedRate = Long.MAX_VALUE)
    public void doInsertUser() {
        final int INSERT_NUM = 1000;
        List<User> list = new ArrayList<>();
        for (int i = 0; i < INSERT_NUM; i++) {
            User user = new User();
            user.setUsername("假Hines");
            user.setUserAccount("fakeHines");
            user.setAvatar("https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png");
            user.setGender((byte) 0);
            user.setUserPassword("12345678");
            user.setPhone("1512616163");
            user.setEmail("12345@qq.com");
            user.setUserStatus(0);
            user.setRole(0);
            user.setTags("[]");
            list.add(user);
        }
        //数据插入进行分批操作（以100个为一批进行插入）
        userService.saveBatch(list, 100);
    }

    /**
     * 使用并发批量插入用户
     */
    //设置定时任务， initialDelay=5000表示项目启动后5秒执行，fixedRate=Long的最大值是让任务只执行一次
//    @Scheduled(initialDelay = 5000,fixedRate = Long.MAX_VALUE)
    public void doConCurrentInsertUser() {

        /*注意创建ThreadPoolExecutor对象所要传入的参数
         * 第一个参数：当前线程池的线程数
         * 第二个参数：当前线程池的最大线程数
         * 第三个参数：线程的存活时间
         * 第四个参数：时间单位（线程到了所设定的时间内没有使用就会自动回收）
         * 第五个参数：任务队列
         * */

        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(60, 100, 10000, TimeUnit.MINUTES, new ArrayBlockingQueue<>(10000));

        final int INSERT_NUM = 100000;// 十万条数据
        //将十万条数据分十组，相当于有十个线程任务
        int j = 0;

        //定义一个任务数组
        List<CompletableFuture<Void>> futureList = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            List<User> list = new ArrayList<>();
            while (true) {
                j++;
                User user = new User();
                user.setUsername("假Hines");
                user.setUserAccount("fakeHines");
                user.setAvatar("https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png");
                user.setGender((byte) 0);
                user.setUserPassword("12345678");
                user.setPhone("1512616163");
                user.setEmail("12345@qq.com");
                user.setUserStatus(0);
                user.setRole(0);
                user.setTags("[]");
                list.add(user);
                if (j % 10000 == 0) {
                    break;
                }
            }
            //新建一个异步的任务,每个任务都去执行saveBatch操作（使用默认的线程池）
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                userService.saveBatch(list, 100);
            }, poolExecutor);
            futureList.add(future);
        }
        //执行这十个任务
        CompletableFuture.allOf(futureList.toArray(new CompletableFuture[]{})).join();
    }
}
